#pragma once
#ifndef Y_DECODER_
#define Y_DECODER_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread> //for std::this_thread
#include <mutex> //for std::mutex
#include "ConsoleLog.h"
#include "utils.h"
#include "YMessageList.h"
#include "YMessageList.h"
#include "MySDLWindow.h"

extern "C" {

#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>

}

class YDecoder : public YMessageListInterface
{
public:
	YDecoder(MySDLWindow* pMyWnd);
	~YDecoder();

	//allow yuv_data to be nullptr,because DecodeToRGB don't need
	//TODO: remove default param
	int DecodeToYuv(uint8_t* h264_data, int h264_len,
		uint8_t* yuv_data, int* yuv_len, int* width, int* height);
	int DecodeToRGB(uint8_t* h264_data, int h264_len,
		uint8_t* rgb_data, int* rgb_len, int* width, int* height);

	//implement of MessageListIngerface
	void ProcessMessage();
	void SendMessage(uint8_t* data, const size_t len);
private:
	void DecodeInternal(uint8_t* data, int* len, int* width,
		int* height, AVPixelFormat format);
	void YuvSave(uint8_t* yuv_data, int* yuv_len);
	int  YuvToRGB(uint8_t* rgb_data, int* rgb_len, int* width,
		int* height);

	AVCodec *codec;
	AVCodecParserContext *parser;
	AVCodecContext *c = NULL;
	AVFrame *frame;
	AVPacket *pkt;
	SwsContext* sc;
	YMessageList* m_pMsg;
	MySDLWindow* m_pMySDLWnd;
	int m_bExit;
	std::mutex m_mutex;
	std::chrono::system_clock::time_point t;
};

#endif //Y_DECODER_